package com.vito.base.listener;

import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vito.base.authoriza.cache.RoleFunCache;
import com.vito.base.authoriza.cache.SessionMap;
import com.vito.base.authoriza.model.FuncModel;
import com.vito.base.authoriza.model.RoleModel;
import com.vito.base.authoriza.model.UserModel;
import com.vito.base.model.Result;
import com.vito.base.util.FileUtil;
import com.vito.base.util.JSONUtil;
import com.vito.base.util.SpringApplicationContext;
import com.vito.base.util.StringUtil;

public class UrlFilterUtil {
	private static Logger log = LoggerFactory.getLogger(UrlFilterUtil.class);
	private static String cookie = null;//写入cookie的配置
	private static Map<String,Object> urlRoleMap = null;
	private static String page_404_msg=null;
	private static String page_404_url=null;
	private static String page_noright_msg=null;
	private static String page_noright_url=null;
	private static String page_nologin_msg=null;
	private static String page_nologin_url=null;
	public static Set<String> passUrl = null;
	private static String loginUrl = null;
	public static void getUrlRoleConfig(){
		urlRoleMap = JSONUtil.convertString2Map(FileUtil.getFileToString("conf/urlFilter.json"));
		if(urlRoleMap!=null){
			Map<String,String> page_404 = (Map<String, String>) urlRoleMap.get("page_404");
			if(page_404!=null){
				page_404_msg = page_404.get("msg");
				page_404_url = page_404.get("redirect_url");
			}
			Map<String,String> page_noright = (Map<String, String>) urlRoleMap.get("page_noright");
			if(page_noright!=null){
				page_noright_msg = page_noright.get("msg");
				page_noright_url = page_noright.get("redirect_url");
			}
			Map<String,String> page_nologin = (Map<String, String>) urlRoleMap.get("page_nologin");
			if(page_noright!=null){
				page_nologin_msg = page_nologin.get("msg");
				page_nologin_url = page_nologin.get("redirect_url");
			}
			List<String> temp = (List<String>) urlRoleMap.get("passUrl");
			if(temp!=null){
				passUrl = new HashSet<String>(temp);
			}
			cookie=(String)urlRoleMap.get("cookie");
			loginUrl = (String) urlRoleMap.get("loginUrl");
			String str =  (String) urlRoleMap.get("isMobileDevice");
			if(str!=null){
				StringUtil.isMobileDevice=str.split(",");
			}
		}
	}
	public static void doFilter(HttpServletRequest request, HttpServletResponse response,
			FilterChain arg2) throws IOException, ServletException {
		SpringApplicationContext.setRequest(request);
		SpringApplicationContext.setResponse(response);
		String uri = request.getRequestURI();
		if(log.isDebugEnabled()){
			log.debug("request ["+uri+"] from "+StringUtil.getIpAddr());
		}
		String sid = null;
		if(cookie!=null&&StringUtil.isMatcher(uri, cookie)){
			sid = SpringApplicationContext.getSessionIdFromCookie(request);
			if(sid==null){
				sid=request.getSession().getId();
			}
			SpringApplicationContext.setSessionIdFromCookie(response, sid);
		}
		//跳过不需要拦截的url
		if(passUrl!=null){
			for (Iterator iterator = passUrl.iterator(); iterator.hasNext();) {
				String string = (String) iterator.next();
				if(StringUtil.isMatcher(uri, string)){
					myDoFilter(request, response,arg2,uri,null);
					return ;
				}
			}
		}
		//验证用户权限
		UserModel user = null;
		if(sid==null){
			user=SessionMap.getObj(request);
		}else{
			user=SessionMap.getObj(sid);
		}
		if(user==null){
			SpringApplicationContext.clearCookie(request,response);
			sendRedirect_login(request,response,loginUrl,Result.CODE_LOGIN_REQUIRE,uri,"-1");
			return ;
		}
		Set<RoleModel> roles = user.getRoles();
		if(roles==null||roles.size()==0){
			sendRedirect(request,response,page_noright_url,Result.CODE_NO_RIGHT,uri,user.getUserId());
			return ;
		}
		for (Iterator<RoleModel> iterator = roles.iterator(); iterator.hasNext();) {
			RoleModel roleModel = iterator.next();
			if(roleModel.getRegexp()!=null&&!"".equals(roleModel.getRegexp())){
				if(StringUtil.isMatcher(uri, roleModel.getRegexp())){
					myDoFilter(request, response,arg2,uri,user.getUserId());
					return ;
				}
			}
		}
		Set<FuncModel> list = getUserMenuList(user);
		String path=request.getContextPath();
		for (Iterator<FuncModel> iterator = list.iterator(); iterator.hasNext();) {
			FuncModel funcModel = iterator.next();
			if(uri.equals(path+StringUtil.getUri(funcModel.getLink()))){
				myDoFilter(request, response,arg2,uri,user.getUserId());
				return ;
			}
		}
		log.warn(user.getUserCode()+"无权限访问===>"+uri);
		sendRedirect(request,response,page_noright_url,Result.CODE_NO_RIGHT,uri,user.getUserId());

	}
	public static void sendRedirect(HttpServletRequest request, HttpServletResponse response,String url,int code,String uri,String userId)  throws IOException, ServletException{
		if(StringUtil.isAjaxRequest(request)||StringUtil.isMobileRequest(request)){
			Result res = new Result();
			res.setCode(code);
			res.setMsg(page_noright_msg);
			response.setContentType("application/json");
			response.setCharacterEncoding("utf-8");
			response.getWriter().write(JSONUtil.converObject2String(res));
			response.getWriter().close();
		}else{
			response.sendRedirect(StringUtil.getWebRootPath()+url);
		}
		UserLog.log(request,response, userId, "noRight");
	}
	public static void sendRedirect_login(HttpServletRequest request, HttpServletResponse response,String url,int code,String uri,String userId)  throws IOException, ServletException{
		/*if(StringUtil.isAjaxRequest(request)||StringUtil.isMobileRequest(request)){
			Result res = new Result();
			res.setCode(code);
			res.setMsg(page_nologin_msg);
			response.setContentType("application/json");
			response.setCharacterEncoding("utf-8");
			response.getWriter().write(JSONUtil.converObject2String(res));
			response.getWriter().close();
		}else{
			response.sendRedirect(StringUtil.getWebRootPath()+url);
		}*/
		response.sendRedirect(StringUtil.getWebRootPath()+url);
		
		UserLog.log(request,response, userId, "noLogin");
	}
	
	static{
		UrlFilterUtil.getUrlRoleConfig();
	}

	/**
	 * 通过用户获取权限列表
	 * 
	 * */
	public static Set<FuncModel> getUserMenuList(UserModel user){
		if(user ==null||user.getRoles()==null||user.getRoles().size()==0){
			return null;
		}
		Set<FuncModel> list = new HashSet<FuncModel>();
		Iterator<RoleModel> it =user.getRoles().iterator();
		while(it.hasNext()){
			try {
				RoleModel role = it.next();
				if(StringUtil.isEmpty(role.getRegexp())){
					list.addAll(getFunctionByRole(role));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return list;
	}
	/**
	 * 通过角色获取权限列表
	 * */
	private static Set<FuncModel> getFunctionByRole(RoleModel role) throws Exception{
		if(role ==null){
			return null;
		}
		Set<FuncModel> list = new HashSet<FuncModel>();
		//Set<FuncModel> fun = (Set<FuncModel>)JedisTool.getMapVal(Contants.CACHE_ROLE_FUN_MAP,role.getRoleId());
		Set<FuncModel> fun = RoleFunCache.getRoleMap(role.getRoleId());
		if(fun!=null){
			list.addAll(fun);
		}
		return list;
	}
	private static void myDoFilter(HttpServletRequest request, HttpServletResponse response,
			FilterChain arg2,String uri,String userId) throws IOException, ServletException {
//		if(StringUtil.isMatcher(uri, cookie)){
//			String sid = SpringApplicationContext.getSessionIdFromCookie(request);
//			if(sid!=null){
//				SpringApplicationContext.setSessionIdFromCookie(response,sid);
//			}
//		}
		UserLog.log(request,response, userId, "");
		arg2.doFilter(request, response);
	}
}



